package com.supermap.desktop.develop.workspacemigration.internalhelpers;

import com.alibaba.fastjson.JSONObject;
import com.supermap.data.EngineType;
import com.supermap.desktop.controls.ControlsResources;
import com.supermap.desktop.core.Application;
import com.supermap.desktop.develop.workspacemigration.constants.SQLConstants;
import com.supermap.desktop.develop.workspacemigration.migration.MigrationConfig;
import org.postgresql.jdbc.PgConnection;
import org.pushingpixels.flamingo.api.common.icon.ResizableIcon;

import java.awt.*;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class InternalHelper {

    private static final String migrationTempFolderName = "MigrationWorkspaces";
    private static final String configFileName = "migration.json";

    private static final String patternRegex = "[A-Za-z0-9_\\-\\u4e00-\\u9fa5]+";
    private static Pattern userNamePattern = Pattern.compile(InternalHelper.patternRegex);

    public static ResizableIcon HelpIcon = ControlsResources.getIcon("/controlsresources/Icon_Help.png").setDimension(new Dimension(16, 16));

    public static String getMigrationTempFolderPath() {
        String systemTempFolderPath = System.getProperty("java.io.tmpdir");
        return systemTempFolderPath.concat("/").concat(migrationTempFolderName);
    }

    public static String getTempDatabaseConfigFilePath() {
        return getMigrationTempFolderPath().concat("/").concat(configFileName);
    }

    public static void updateMigrationConfig(MigrationConfig config) {
        String configJSONContent = JSONObject.toJSONString(config);

        String tempDatabaseConfigFilePath = getTempDatabaseConfigFilePath();
        File configFile = new File(tempDatabaseConfigFilePath);
        if (configFile.exists()) {
            configFile.delete();
        }
        try {
            if (configFile.createNewFile()) {
                FileWriter fileWriter = new FileWriter(configFile);
                fileWriter.write(configJSONContent);
                fileWriter.flush();
                fileWriter.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static MigrationConfig loadMigrationConfig() {
        MigrationConfig migrationConfig = null;

        String tempDatabaseConfigFilePath = getTempDatabaseConfigFilePath();
        File configFile = new File(tempDatabaseConfigFilePath);
        if (!configFile.exists()) {
            return migrationConfig;
        }

        String configContent = "";
        try {
            FileReader fileReader = new FileReader(configFile);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String content = "";
            do {
                configContent = configContent.concat(content);
                content = bufferedReader.readLine();
            } while (content != null && !content.equals(""));
            bufferedReader.close();
            fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (!configContent.equals("")) {
            JSONObject jsonObject = (JSONObject) JSONObject.parse(configContent);
            migrationConfig = JSONObject.toJavaObject(jsonObject, MigrationConfig.class);
        }
        return migrationConfig;
    }

    public static ArrayList<String> queryWorkspaceNames(String srcIP, String srcPort, String srcDatabaseName,
                                                        String userName, String password, EngineType engineType) {
        ArrayList<String> srcWorkspaceNames = new ArrayList<>();

        try {
            Class.forName(SQLHelper.getDatabaseDriver(engineType));
            String url = SQLHelper.getJDBCDriver(engineType).concat(srcIP).concat(":").concat(srcPort).concat("/").concat(srcDatabaseName);
            Connection srcConnection = DriverManager.getConnection(url, userName, password);
            if (!srcConnection.isClosed()) {
                String sql = "select ".concat(SQLConstants.SMWorkspaceField).concat(" from ").concat(SQLConstants.SMWorkspaceSystemTableName);
                if (engineType == EngineType.POSTGRESQL || engineType == EngineType.PGGIS) {
                    PgConnection pgConnection = (PgConnection) srcConnection;
                    Statement statement = pgConnection.createStatement();
                    ResultSet resultSet = statement.executeQuery(sql);
                    while (resultSet.next()) {
                        String workspaceName = resultSet.getString(SQLConstants.SMWorkspaceField);
                        srcWorkspaceNames.add(workspaceName);
                    }
                    resultSet.close();
                    statement.close();
                    pgConnection.close();
                }
            }
        } catch (Exception e) {
            Application.getActiveApplication().getOutput().output(e);
        }

        return srcWorkspaceNames;
    }

    public static void clearMigrationTempResources() {
        String migrationTempFolderPath = InternalHelper.getMigrationTempFolderPath();
        File file = new File(migrationTempFolderPath);
        if (file.isDirectory()) {
            File[] tempLibraryFiles = file.listFiles(pathname -> {
                String name = pathname.getName();
                return pathname.isFile() && (name.endsWith(".bru") || name.endsWith(".lsl") || name.endsWith(".sym"));
            });
            for (File tempLibraryFile : tempLibraryFiles) {
                tempLibraryFile.delete();
            }
        }
    }

    public static String getAvailableUserName(String userName) {
        Matcher matcher = InternalHelper.userNamePattern.matcher(userName);
        ArrayList<String> names = new ArrayList<>();
        while (matcher.find()) {
            names.add(matcher.group());
        }
        String username = "";
        int groupCount = names.size();
        for (int k = 0; k < groupCount; k++) {
            username = username.concat(names.get(k));
            if (k < groupCount - 1) {
                username = username.concat("_");
            }
        }
        names.clear();
        return username;
    }
}
